#include "global.h"

Global::Global(){}
QFont Global::IconFont;
QStringList Global::apiHost = {"cloud.lightrim.cn", "80"};
QString Global::httpInterface = "https://cloud.lightrim.cn/v2";
QString Global::apiInterface = "https://cloud.lightrim.cn/v2/lrCloudPlatform.php";
QString Global::apiToken = "qGwa1m3Xo0rHdB5q2";

QString Global::aiApiInterface = "TencentDeepSeek";
double Global::aiUnitPrice = 0.05;

QString Global::deepseekApi = "https://api.deepseek.com/chat/completions";
QString Global::deepseekApiKey = "sk-cf39aabca5fd415384aa9272bbb8fe3d";
QString Global::deepseekModel = "deepseek-chat";

QString Global::tencentApi = "https://lkeap.tencentcloudapi.com";
QString Global::deepseekApiToken = "sk-9cKHA7nUYRB7sDP3TUssnQlk7lclbpI9nUezaaII4KOPTH3w";
QString Global::tencentSecretId = "AKIDrLkx0ufEvQlurbCZlkaxBD4iASWN3Xpu";
QString Global::tencentSecretKey = "vgEajxJYgoqwxBNxNabO2Tlx1vvjLkww";
QString Global::tencentModel = "deepseek-v3-0324";

QString Global::deepseekRoleSystem = "你是一个小水电行业专家.";
QStringList Global::iRedis = {"47.112.230.185","6379","P4C52yDseLdjCJhi"};
QNetworkAccessManager *Global::NetworkManager;
QString Global::CompanyName = "上海廉容自动化技术有限公司";
QString Global::PlatformName = "廉容水电站云集控运维中心";  //默认的平台名称
QJsonObject Global::usrLoggedInfo; //登录信息
QStringList Global::lstSuperUser;   //超级用户
QString Global::strAuthority = "0";
QStringList Global::lstAuthority = {"1","2","9"};
QJsonObject Global::usrSettingsInfo; //用户设置信息
QString Global::fiConfig = "app.ini";
QString Global::logdir = "log";

QString Global::appClientID = "LrCloudPlatform";
QString Global::appDeviceNumber = ""; //当前平台使用的设备ID
QMap<QString, QStringList> Global::DefArea; //默认的用户区域
QJsonArray Global::usrBindDevices;  //用户绑定的设备信息
QJsonObject Global::lstDataCache;   //当前设备列表的实时数据
QMap<QString, QJsonObject> Global::devDataCache;  //当前(RealData)/轮播(CarouselData)设备MQTT实时数据
QString Global::hasOptionPasswd = "0";  //是否每次打开详情都要输入密码
QString Global::CurrDevNumber;  //当前设备的ID号
QString Global::CurrDevNumberPasswd;  //当前设备的操作密码
QJsonObject Global::CurrDeviceInfo; //当前操作设备的基本信息
QString Global::CarouselDevNumber = "";  //当前轮播设备的ID号
qint64 Global::devDataListTime = 0;   // 接收到的实时数据的最后时间

double Global::nFaDianLing = 0; //年发电量
QStringList Global::AlarmItem;
QMap<int, QString> Global::AlarmText;
QStringList Global::dev2StateText;  // 2.0状态码，定义在V20Main.cpp中
QString Global::idMqttMessage;

// 摄像头
QString Global::strCameraIP = "192.168.2.200";
QString Global::strCameraUser = "admin";
QString Global::strCameraPass = "light168";
int Global::itCameraRtspPort = 554;
QString Global::strCameraPath = "/ISAPI/Streaming/Channels/102";
// 流媒体服务器
QString Global::strStreamServer = "47.103.69.73";
int Global::strStreamRtspPort = 8554;
QString Global::strMediaMTXUser = "admin";
QString Global::itMediaMTXPass = "light168";
QString Global::strStreamName = "office_cam_low";

/* *************
 * @brief 初始化INI配置
 * *************/
void Global::fnInitializationConfig(){
    //QWebEngineView配置
    //禁用非必要功能提升速度
    qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-features=TranslateUI,BlinkGenPropertyTrees");
    qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-features=Perfetto"); // 禁用 Perfetto 追踪
    qputenv("QTWEBENGINE_DISABLE_PDF", "1");    //关闭 PDF 查看器
    qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-software-rasterizer --disable-gpu");   //调整 JavaScript 定时器精度
    qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-site-isolation-trials");   //合并进程节省资源
    //启用远程调试
    /*
    qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "9222");
    qputenv("QTWEBENGINE_CHROMIUM_FLAGS",
            "--remote-debugging-address=127.0.0.1 --remote-debugging-port=9222");
    */
    //若遇到驱动兼容性问题，可尝试 ANGLE 或软件回退
    //qputenv("QT_WEBENGINE_CHROMIUM_FLAGS", "--enable-gpu-rasterization --enable-oop-rasterization");

    // 在应用启动时预加载 WebEngine 环境
    QTimer::singleShot(0, nullptr, [=]() {
        QWebEngineView *preloader = new QWebEngineView();
        preloader->load(QUrl("about:blank")); // 触发进程初始化
        preloader->deleteLater(); // 稍后销毁
    });

    // 设置预连接 DNS（需替换为网页的域名）
    QNetworkRequest request(QUrl(QString("%1").arg(Global::httpInterface)));
    request.setRawHeader("Host", Global::apiHost.at(0).toLatin1());
    Global::NetworkManager = new QNetworkAccessManager();
    Global::NetworkManager ->connectToHost(Global::apiHost.at(0).toLatin1(), Global::apiHost.at(1).toInt());

    Global::DefArea.insert("prov", {"360000","江西省"});
    Global::DefArea.insert("city", {"360700","赣州市"});
    Global::DefArea.insert("dist", {"360702","章贡区"});

    Global::AlarmItem.append("AnalogQuantityValue1");
    Global::AlarmItem.append("AnalogQuantityValue2");
    Global::AlarmItem.append("AnalogQuantityValue3");
    Global::AlarmItem.append("AnalogQuantityValue4");
    Global::AlarmItem.append("AnalogQuantityValue5");
    Global::AlarmItem.append("AnalogQuantityValue6");
    Global::AlarmItem.append("AnalogQuantityValue7");
    Global::AlarmItem.append("AnalogQuantityValue8");
    Global::AlarmItem.append("AnalogQuantityCollect1");
    Global::AlarmItem.append("AnalogQuantityCollect2");
    Global::AlarmItem.append("AnalogQuantityCollect3");
    Global::AlarmItem.append("AnalogQuantityCollect4");
    Global::AlarmItem.append("AnalogQuantityCollect5");
    Global::AlarmItem.append("AnalogQuantityCollect6");
    Global::AlarmItem.append("AnalogQuantityCollect7");
    Global::AlarmItem.append("AnalogQuantityCollect8");

    Global::AlarmText.insert(0, "水位泄洪报警");
    Global::AlarmText.insert(1, "正在执行（水位）开机流程");
    Global::AlarmText.insert(2, "完成（水位）开机流程");
    Global::AlarmText.insert(3, "正在执行（水位）停机流程");
    Global::AlarmText.insert(4, "完成（水位）停机流程，已停机");
    Global::AlarmText.insert(5, "正在执行（手动）开机流程");
    Global::AlarmText.insert(6, "完成（手动）开机流程");
    Global::AlarmText.insert(7, "正在执行（手动）停机流程");
    Global::AlarmText.insert(8, "完成（手动）停机流程，已停机");
    Global::AlarmText.insert(9, "紧急停机（缺相）");
    Global::AlarmText.insert(10, "紧急停机（过流）");
    Global::AlarmText.insert(11, "紧急停机（事故）");
    Global::AlarmText.insert(12, "设备正常，正在并网发电");
    Global::AlarmText.insert(13, "正在执行（温度）停机流程");

    QSettings settings(Global::fiConfig, QSettings::IniFormat);
    settings.setIniCodec("utf-8");
    settings.beginGroup("General");
    QString usrInfo = settings.value("usrLoggedInfo").toString();
    QJsonDocument jsonDocument = QJsonDocument::fromJson(usrInfo.toUtf8().data());
    if(!jsonDocument.isNull()){
        Global::usrLoggedInfo = jsonDocument.object();
    }

    // if(!settings.contains("PlatformName"))
    //     settings.setValue("PlatformName", Global::PlatformName);
    // else Global::PlatformName = settings.value("PlatformName").toString();

    if(!settings.contains("hasOptionPasswd"))
        settings.setValue("hasOptionPasswd", Global::hasOptionPasswd);
    else Global::hasOptionPasswd = settings.value("hasOptionPasswd").toString();

    if(!settings.contains("aiApiInterface"))
        settings.setValue("aiApiInterface", Global::aiApiInterface);
    else Global::aiApiInterface = settings.value("aiApiInterface").toString();

    if(!settings.contains("deepseekModel"))
        settings.setValue("deepseekModel", Global::deepseekModel);
    else Global::deepseekModel = settings.value("deepseekModel").toString();

    if(!settings.contains("tencentModel"))
        settings.setValue("tencentModel", Global::tencentModel);
    else Global::tencentModel = settings.value("tencentModel").toString();
    settings.endGroup();

    settings.beginGroup("Camera");
        if(!settings.contains("strCameraIP"))
            settings.setValue("strCameraIP", Global::strCameraIP);
        else Global::strCameraIP = settings.value("strCameraIP").toString();
        if(!settings.contains("strCameraUser"))
            settings.setValue("strCameraUser", Global::strCameraUser);
        else Global::strCameraUser = settings.value("strCameraUser").toString();
        if(!settings.contains("strCameraPass"))
            settings.setValue("strCameraPass", Global::strCameraPass);
        else Global::strCameraPass = settings.value("strCameraPass").toString();
        if(!settings.contains("itCameraRtspPort"))
            settings.setValue("itCameraRtspPort", Global::itCameraRtspPort);
        else Global::itCameraRtspPort = settings.value("itCameraRtspPort").toInt();
        if(!settings.contains("strCameraPath"))
            settings.setValue("strCameraPath", Global::strCameraPath);
        else Global::strCameraPath = settings.value("strCameraPath").toString();

        if(!settings.contains("strStreamServer"))
            settings.setValue("strStreamServer", Global::strStreamServer);
        else Global::strStreamServer = settings.value("strStreamServer").toString();
        if(!settings.contains("strStreamRtspPort"))
            settings.setValue("strStreamRtspPort", Global::strStreamRtspPort);
        else Global::strStreamRtspPort = settings.value("strStreamRtspPort").toInt();
        if(!settings.contains("strMediaMTXUser"))
            settings.setValue("strMediaMTXUser", Global::strMediaMTXUser);
        else Global::strMediaMTXUser = settings.value("strMediaMTXUser").toString();
        if(!settings.contains("itMediaMTXPass"))
            settings.setValue("itMediaMTXPass", Global::itMediaMTXPass);
        else Global::itMediaMTXPass = settings.value("itMediaMTXPass").toString();
        if(!settings.contains("strStreamName"))
            settings.setValue("strStreamName", Global::strStreamName);
        else Global::strStreamName = settings.value("strStreamName").toString();
    settings.endGroup();

    //检查log文件夹是否存在
    QString logpath = QString("%1/%2").arg(qApp->applicationDirPath(),Global::logdir);
    QDir dir(logpath);
    if(!dir.exists())
        dir.mkdir(logpath);

    Global::lstSuperUser.append("13879767836");
    Global::lstSuperUser.append("18070279402");
}

/* *************
 * @brief 保存用户的操作及DEBUG日志
 * @param cont 内容组:(0)account;(1)cont
 * *************/
void Global::fnSaveOperation(QString cont){
    QString finame = QDate::currentDate().toString("yyyyMMdd");
    QString fipath = QString("%1/%2/%3.txt").arg(qApp->applicationDirPath(),Global::logdir,finame);
    QFile fi(fipath);
    if(!fi.open(QIODevice::WriteOnly | QIODevice::Append))
        return;
    class QStringList lst;
    lst.push_back(QTime::currentTime().toString("hh:mm:ss"));
    lst.push_back(Global::usrLoggedInfo.value("mobile").toString());
    lst.push_back(QString("%1\r\n").arg(cont));
    QTextStream txtOutput(&fi);
    QTextCodec *codec = QTextCodec::codecForName("utf-8");
    QTextCodec::setCodecForLocale(codec);
    txtOutput << lst.join(" ");
    fi.close();
}

/* *************
 * @brief 修改单条INI配置
 * @param fiPath 路径
 * @param iValue 值
 * *************/
void Global::fnWriteConfigSingle(QStringList fiConfigValue){
    if(fiConfigValue.size() < 2){
        Global::fnSaveOperation("修改INI配置失败！参数长度不匹配。");
        return;
    }
    QSettings settings(Global::fiConfig, QSettings::IniFormat);
    settings.setIniCodec("utf-8");
    settings.setValue(fiConfigValue.at(0), fiConfigValue.at(1));
}

/* *************
 * @brief http POST发送和接收接口，收发同步
 * @param httpParameter http发送数据组包
 * @param errmsg http返回的错误信息
 * @param result http接收响应
 * *************/
void Global::fnHttpRequest(QJsonObject httpParameter, QString &errMessage, QString &reqResult, QString url){
    if (!Global::NetworkManager) {
        errMessage = "Network manager not initialized";
        return;
    }
    QNetworkRequest oNetRequest;
    oNetRequest.setUrl(url == "" ? QUrl(Global::apiInterface) : QUrl(url));
    oNetRequest.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));
    oNetRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);

    if(oNetRequest.url() == Global::apiInterface){
        QDateTime local((QDateTime::currentDateTime()));
        httpParameter.insert("TOKEN",QString("%1%2").arg(Global::apiToken, local.toString("yyyyMMdd")));
    }
    // qDebug() << __func__ << __LINE__ << "httpParameter" << httpParameter;

    QJsonDocument httpDocum;
    httpDocum.setObject(httpParameter);
    QByteArray arrHttpParameter = httpDocum.toJson(QJsonDocument::Compact);
    
    QNetworkReply *oNetReply = Global::NetworkManager->post(oNetRequest, arrHttpParameter);
    if (!oNetReply) {
        errMessage = "Failed to create network reply";
        return;
    }
    /*
    qDebug() << "=== Request ===";
    qDebug() << "Request URL:" << oNetRequest.url();
    qDebug() << "Request Headers:" << oNetRequest.rawHeaderList();
    qDebug() << "Parameters:" << httpParameter;
    */
    QEventLoop eventloop;
    QEventLoop::connect(oNetReply, SIGNAL(finished()), &eventloop, SLOT(quit()));
    QTimer::singleShot(10000, &eventloop, &QEventLoop::quit);
    eventloop.exec();

    if(oNetReply->isFinished()){
        if(oNetReply->error() == QNetworkReply::NoError && oNetReply->bytesAvailable() > 0){
            reqResult = oNetReply->readAll();
            /* qDebug() << "=== Response ===";
            qDebug() << "Hex Response:" << reqResult.toUtf8().toHex();
            qDebug() << "Status:" << oNetReply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
            qDebug() << "Body:" << reqResult; */
        }else{
            errMessage = oNetReply->errorString();
            // qDebug() << "=== Error ===" << errMessage;
        }
    }else{
        QEventLoop::disconnect(oNetReply, &QNetworkReply::finished, &eventloop, &QEventLoop::quit);
        errMessage = "API Request Timeout.";
    }

    QNetworkReply::NetworkError e = oNetReply->error();
    if (e){
        errMessage = oNetReply->errorString();
        qDebug() << "=== Timeout ===";
    }

    oNetReply->abort();
    oNetReply->close();
    oNetReply->deleteLater();
}

/**
 * @brief readJsFile
 * @param filePath
 * @return
 * 读取本地 JS 文件内容
 */
QString Global::fnReadJsFile(const QString &filePath){
    QFile jsFile(filePath);
    if (!jsFile.open(QIODevice::ReadOnly | QIODevice::Text))
        return QString("Failed to open JS file:%1").arg(filePath);
    QTextStream jsStream(&jsFile);
    QString jsContent = jsStream.readAll();
    jsFile.close();
    return jsContent;
}

/**
 * @brief fnDataUpdate
 * @param parameter
 * 发送远控消息
 */
void Global::fnDataUpdate(QJsonObject parameter, QString &idMqttMessage){
    QStringList param = {"ShowMessages", "5", "正在发送数据，耐心等待一会！"};
    emit MGlobal::fnGetInstance()->CallInsidePageAction(param);
    param.clear();

    QString iptAddr = parameter.value("iptAddr").toString(),
        iptValue = parameter.value("iptValue").toString();
    if(idMqttMessage != "noWaiting")
        idMqttMessage = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");

    QJsonObject data = Global::devDataCache.value("RealData");
    float version = data.value("VersionName").toString().leftRef(3).toFloat();

    QJsonObject mqttData;
    mqttData.insert("appClientID", Global::appClientID);
    mqttData.insert("appNumber", Global::appDeviceNumber);
    mqttData.insert("usrPasswd", Global::CurrDevNumberPasswd);
    if(version < 2.0)
        mqttData.insert("iptAddr", iptAddr);
    else mqttData.insert("iptAddr", iptAddr.toInt());
    mqttData.insert("iptValue", iptValue);

    QJsonObject sendData;
    sendData.insert("MsgType", "APPUPDATA");
    sendData.insert("MqttData", mqttData);

    QJsonObject sendParam;
    sendParam.insert("idMqttMessage", idMqttMessage);
    sendParam.insert("topic", QString("/%1/%2").arg(Global::CurrDeviceInfo.value("deviceClientID").toString(),
                                                    Global::CurrDeviceInfo.value("deviceNumber").toString()));
    sendParam.insert("qos", "2");
    sendParam.insert("sendData", sendData);

    QJsonDocument document(sendParam);
    QString dataString = document.toJson(QJsonDocument::Compact);

    // 发送MQTT消息
    param.append(dataString);
    param.append("SendMqttMessage");
    emit MGlobal::fnGetInstance()->CallInsidePageAction(param);
    param.clear();
}

/*****************************
** 非阻塞延时
** @param msec 毫秒
** *************/
void Global::fnExecSleep(int msec){
    QEventLoop eventloop;
    QTimer::singleShot(msec, &eventloop, SLOT(quit()));
    eventloop.exec();
}
